package uk.ac.warwick.dcs.csufbo;

import java.io.File;
import java.io.IOException;
import javax.sound.midi.InvalidMidiDataException;
import javax.sound.midi.MidiEvent;
import javax.sound.midi.MidiSystem;
import javax.sound.midi.Sequence;
import javax.sound.midi.Track;

//Read in midi files and build markov chains
public class MidiAnalyser
{
	String strFilename;
	String[] strFilenames;
	File midiFile;
	Sequence sequence;
	Track[] tracks;
	Double[][] mChain;
	Double[][] tempChain;
	Integer noteValue;
	Integer lastNote;

	public MidiAnalyser()
	{
		initChain();
	}

	
	public MidiAnalyser(String xiFilename)
	{
		this.strFilename = xiFilename;

		initChain();
		midiFile = new File(xiFilename);
		addSequence(midiFile);
	}

	public MidiAnalyser(String[] xiFilenames)
	{
		this.strFilenames = xiFilenames;

		initChain();

		for (int i = 0; i < xiFilenames.length; i++)
		{
			midiFile = new File(xiFilenames[i]);
			addSequence(midiFile);
		}
	}

	public Double[][] getMChain()
	{
		double colTotal;
		
		mChain = new Double[12][12];
		
		for (int i = 0; i < tempChain.length; i++)
			mChain[i] = tempChain[i].clone();

		for (int z = 0; z < mChain.length; z++)
		{
			colTotal = 0;
			for (int k = 0; k < mChain[z].length; k++)
			{
				colTotal = colTotal + mChain[z][k];
			}

			for (int k = 0; k < mChain[z].length; k++)
			{
				mChain[z][k] = mChain[z][k] / colTotal;
			}
		}

		return mChain;
	}

	public void addSequence(File file)
	{

		midiFile = file;
		noteValue = new Integer(0);
		lastNote = new Integer(0);

		try
		{
			sequence = MidiSystem.getSequence(midiFile);
			tracks = sequence.getTracks();

			if (tracks != null)
			{
				for (int i = 0; i < tracks.length; i++)
				{
					System.out.println("Track " + i + ":");
					Track track = tracks[i];
					for (int j = 0; j < track.size(); j++)
					{
						MidiEvent event = track.get(j);
						if (event.getMessage().getStatus() == 144)
						{
							noteValue = event.getMessage().getMessage()[1] % 12;
							System.out.println(" tick " + event.getTick()
									+ ", " + noteValue);
							tempChain[lastNote.intValue()][noteValue.intValue()] = tempChain[lastNote
									.intValue()][noteValue.intValue()] + 1;
							lastNote = noteValue;
						}
					}
				}
			}

		}
		catch (InvalidMidiDataException e)
		{
			e.printStackTrace();
			System.exit(1);
		}
		catch (IOException e)
		{
			e.printStackTrace();
			System.exit(1);
		}


	}

	private void initChain()
	{
		tempChain = new Double[12][12];

		for (int i = 0; i < tempChain.length; i++)
		{
			for (int j = 0; j < tempChain[i].length; j++)
			{
				tempChain[i][j] = new Double(0);
			}
		}
	}
}
